package magicboard.classifier.feature
{
	import magicboard.classifier.feature.features.FeatureExtractor;
	import magicboard.classifier.patterndb.PatternDB;
	import magicboard.model.InkStroke;
	
	public class Pattern
	{
		// --------------------------------------------------------------------------------------------
		public function Pattern(n:String, f:Object){
			
			_name = n;
			_features = f;
		}
		
		// --------------------------------------------------------------------------------------------
		/**
		 * @return Array with all patterns
		 */
		public static function createAllPatterns():Array {
			var patterns:Array = new Array();
			
			for (var cls:String in PatternDB.classes){
				patterns = patterns.concat(Pattern.loadPatterns(cls));
			}	
			
			return patterns;
		}
		
		
		// --------------------------------------------------------------------------------------------
		private static function loadPatterns(label:String):Array{
			var patterns:Array = new Array();
			var featureExtractors:Array = new Array();
			var index:int;
			var fe:FeatureExtractor;
			
			// Get features
			for each ( var fname:String in PatternDB.classes[label] ){
 				fe = FeatureExtractor.extractors[fname];
      			
  			if(fe != null)
  				featureExtractors.push(fe);
			} 
						
			// Get features
			for each ( var reference:String in PatternDB.references[label] ){
	  		// Load pattern
	  		var values:Object = new Object();
	  		var stroke:InkStroke = new InkStroke();
	  		stroke.loadFromString(label+":"+reference);
	  		
	  		for each(fe in featureExtractors){
	  			values[fe.id] = fe.extract(stroke);
	  		}
	  		patterns.push(new Pattern(label, values));
   		}
			
			return patterns;
		}
		
		// --------------------------------------------------------------------------------------------
		public function get name():String { return _name};
		
		// --------------------------------------------------------------------------------------------
		/**
		 * Calculate distance for the given feature
		 */
		public function distance(features:Object):Number{
			
			var distance:Number = 0;
			
			for (var key:String in features){
				distance += Math.abs(_features[key] - features[key]);
			}
			
			return distance;
		}

		// --------------------------------------------------------------------------------------------
		// Private members
		private var _features:Object;
		private var _name:String;
		
	}
}